"""
德州扑克位置系统模块。
提供位置验证、转换和关系判断等功能。
"""
from typing import Dict, List

# 不同玩家数量下的位置映射
POSITION_MAP: Dict[int, List[str]] = {
    9: ['UTG', 'UTG+1', 'UTG+2', 'LJ', 'HJ', 'CO', 'BTN', 'SB', 'BB'],
    8: ['UTG', 'UTG+1', 'LJ', 'HJ', 'CO', 'BTN', 'SB', 'BB'],
    7: ['UTG', 'LJ', 'HJ', 'CO', 'BTN', 'SB', 'BB'],
    6: ['UTG', 'HJ', 'CO', 'BTN', 'SB', 'BB'],
    5: ['UTG', 'CO', 'BTN', 'SB', 'BB'],
    4: ['CO', 'BTN', 'SB', 'BB'],
    3: ['BTN', 'SB', 'BB'],
    2: ['SB', 'BB']
}

class InvalidPositionError(ValueError):
    """无效的位置"""
    pass

class InvalidPlayerCountError(ValueError):
    """无效的玩家数量"""
    pass

class Position:
    """
    德州扑克位置系统
    处理位置验证、转换和关系判断等功能
    """
    
    @staticmethod
    def get_positions(num_players: int) -> List[str]:
        """
        获取指定玩家数量下的所有位置列表
        Args:
            num_players: 玩家数量
        Returns:
            List[str]: 位置列表，从早位到晚位排序
        Raises:
            InvalidPlayerCountError: 如果玩家数量不在2-9之间
        """
        if num_players not in POSITION_MAP:
            raise InvalidPlayerCountError(f"Invalid player count: {num_players}, must be between 2 and 9")
        return POSITION_MAP[num_players]
        
    @staticmethod
    def is_valid_position(position: str, num_players: int) -> bool:
        """
        检查位置在给定玩家数下是否合法
        Args:
            position: 位置名称
            num_players: 玩家数量
        Returns:
            bool: 位置是否合法
        """
        try:
            positions = Position.get_positions(num_players)
            return position in positions
        except InvalidPlayerCountError:
            return False
            
    @staticmethod
    def get_position_index(position: str, num_players: int) -> int:
        """
        获取位置在给定玩家数下的索引
        Args:
            position: 位置名称
            num_players: 玩家数量
        Returns:
            int: 位置索引（0为最早位）
        Raises:
            InvalidPositionError: 如果位置在当前玩家数下不合法
            InvalidPlayerCountError: 如果玩家数量不合法
        """
        positions = Position.get_positions(num_players)
        try:
            return positions.index(position)
        except ValueError:
            raise InvalidPositionError(f"Invalid position '{position}' for {num_players} players")
            
    @staticmethod
    def get_position_name(index: int, num_players: int) -> str:
        """
        根据索引和玩家数获取位置名称
        Args:
            index: 位置索引（0为最早位）
            num_players: 玩家数量
        Returns:
            str: 位置名称
        Raises:
            InvalidPositionError: 如果索引超出范围
            InvalidPlayerCountError: 如果玩家数量不合法
        """
        positions = Position.get_positions(num_players)
        if not 0 <= index < len(positions):
            raise InvalidPositionError(f"Invalid position index {index} for {num_players} players")
        return positions[index]
        
    @staticmethod
    def is_position_before(position1: str, position2: str, num_players: int) -> bool:
        """
        判断position1是否在position2前面
        Args:
            position1: 第一个位置
            position2: 第二个位置
            num_players: 玩家数量
        Returns:
            bool: 如果position1在position2前面则返回True
        Raises:
            InvalidPositionError: 如果任一位置不合法
            InvalidPlayerCountError: 如果玩家数量不合法
        """
        index1 = Position.get_position_index(position1, num_players)
        index2 = Position.get_position_index(position2, num_players)
        return index1 < index2 